<template>
  <base-modal :title="$t('formSetting.jsCodeBlock.jsCodeTest')" :show.sync="visible" :allow-auto-close="false" width="800px" class="compilation-test-modal" @close="onClose" v-if="visible">
    <div class="tab-steps-body">
      <div class="tab-steps">
        <!--start 步骤条 -->
        <compile-steps :step-data="stepData" :active="active"></compile-steps>
        <!--end 步骤条 -->
      </div>
      <div class="tab-step" v-if="active == 0">
        <cm-editor @handleCodemirrorChange="handleCodemirrorChange" :can-inserted-fields="canInsertedFields" :code="codeBlockConfig.codeContent"></cm-editor>
      </div>
      <div class="tab-step" v-if="active == 1">
        <test-run ref="testRun" :result-alias-path="resultAliasPath" :code="codeBlockConfig.codeContent" :fields="insertFields" :analysis-results="analysisResults" :field="field" @compilerResult="compilerResult"></test-run>
      </div>
      <div class="tab-step" v-if="active == 2">
        <return-parse ref="returnParse" :result-alias-path="resultAliasPath" :analysis-results="analysisResults" :field="field" @outResultAliasPath="outResultAliasPath"></return-parse>
      </div>
    </div>

    <div slot="footer" class="dialog-footer">
      <el-button @click="onClose" autofocus v-if="active==0">{{ $t('buttons.cancel') }}</el-button>
      <el-button type="primary" @click="submit" :disabled="!codeBlockConfig.codeContent" v-if="active == 0" >{{ $t('formSetting.jsCodeBlock.saveNextStep') }}</el-button>
      <el-button v-if="active!==0" @click="onBack" >{{ $t('formSetting.jsCodeBlock.backStep') }} </el-button>
      <el-button type="primary" @click="submit" :disabled="pending || !resultAliasPath.length" v-show=" active == 1">{{ $t('formSetting.jsCodeBlock.nextStep') }}</el-button>
      <el-button type="primary" @click="submit" v-if="active == 2">{{ $t('formSetting.jsCodeBlock.complete') }} </el-button>
    </div>
  </base-modal>
</template>
<script>
import cmEditor from './cmEditor';
import testRun from './testRun.vue';
import returnParse from './returnParse.vue';
import {checkJsCode, isObjectString} from '../model/index';

import _, {cloneDeep, isString} from 'lodash';
import {CustomerFieldNameMappingEnum, FieldTypeMappingEnum} from "@model/enum/FieldMappingEnum";
// import sysFields from "@src/view/template/list/util/sysFields";
import platform from "@src/platform";
import i18n from "@src/locales";
import { isInSubForm } from '@src/component/form/util/index';
import compileSteps from '@src/component/form/components/FormJsControl/components/compileSteps.vue'

const SUPPORT_INSER_TEDFIELD = [
  // 基础字段
  FieldTypeMappingEnum.Text,
  FieldTypeMappingEnum.Textarea,
  FieldTypeMappingEnum.Number,
  FieldTypeMappingEnum.Select,
  FieldTypeMappingEnum.Cascader,
  FieldTypeMappingEnum.User,
  FieldTypeMappingEnum.Date,
  FieldTypeMappingEnum.Phone,
  FieldTypeMappingEnum.Email,
  FieldTypeMappingEnum.Address,
  FieldTypeMappingEnum.Location,
  FieldTypeMappingEnum.Formula,
  FieldTypeMappingEnum.SubForm,
  // FieldTypeMappingEnum.SparePart,
  // FieldTypeMappingEnum.ServiceItem,
  // FieldTypeMappingEnum.MaterialOrder,
  // FieldTypeMappingEnum.Pay,
  // FieldTypeMappingEnum.RelatedTask,
  // CustomerFieldNameMappingEnum.Customer,
  // FieldTypeMappingEnum.Product,
  CustomerFieldNameMappingEnum.CustomerAddress,
  CustomerFieldNameMappingEnum.Linkman,
  // FieldTypeMappingEnum.OutWarehouse,
  // FieldTypeMappingEnum.InWarehouse,
  // FieldTypeMappingEnum.InSparepart,
  // FieldTypeMappingEnum.OutSparepart,
  // FieldTypeMappingEnum.CurrencyCode

  // 业务字段
  'taskNo',
];
export default {
  name:'compilation-test-dialog',
  components: {
    [cmEditor.name]: cmEditor,
    [testRun.name]: testRun,
    [returnParse.name]: returnParse,
    [compileSteps.name]: compileSteps
  },
  props: {
    field: {
      type: Object,
      default: () => ({})
    },
    fields: {
      type: Array,
      default: () => ([])
    },
  },
  data() {
    return {
      visible: false,
      pending: true,
      active: 0,
      analysisResults: '',
      stepData: [this.$t('formSetting.jsCodeBlock.coding'), this.$t('formSetting.jsCodeBlock.testRun'), this.$t('formSetting.jsCodeBlock.returnParsing')],
      insertFields: [],
      codeBlockConfig: {
        automaticOperation: 0,
        codeContent:'', // js代码块
        resultAliasPath:[], // 创建别名
      }
    };
  },
  computed: {
    /* 能插入的表单字段别名 */
    resultAliasPath() {
      return this.codeBlockConfig?.resultAliasPath || [];
    },
    /* 能插入的表单字段 */
    canInsertedFields() {
      if (isInSubForm(this.field)) {
        const parentFields = this.fields.find(field => field.fieldName === this.field.parentFieldName);
        const subFormFieldList = parentFields?.subFormFieldList || [];
        return subFormFieldList.filter(
          field => SUPPORT_INSER_TEDFIELD.includes(field.formType)
        )
      } else {
        return this.fields.filter(
          field => SUPPORT_INSER_TEDFIELD.includes(field.formType)
        ).concat([].filter(field => !['assignUser', 'USER_DEPARTMENT', 'CURRENT_NODE'].includes(field.fieldName)));
      }
    },
  },
  watch: {
    visible(newValue) {
      if(newValue) {
        // 初始化数据
        const { codeBlockConfig = {} } = this.field.setting;
        const code = codeBlockConfig?.codeContent || '';
        if(code) {
          this.codeBlockConfig = _.cloneDeep(codeBlockConfig);
          this.insertFields = this.getInsertFields(code);
        }
        this.active = 0;
      }
    },
  },
  mounted() {},
  methods:{
    /** 上一步 */
    onBack() {
      if(this.active > 0) {
        this.active--;
      }
    },
    checkedAliasNameIsEmptyOrRepeatAndDangerCode () {
      return new Promise((resolve, reject)=> {
        const resultAliasPath = this.codeBlockConfig.resultAliasPath;
        const isNullAliasName = resultAliasPath.some(item => !item.aliasName || item.aliasName.match(/^\s*$/));
        const isRepeatName = resultAliasPath.some((obj, index) => {
          return resultAliasPath.findIndex((item, idx) => idx !== index && item.aliasName === obj.aliasName) !== -1;
        });

        if( isNullAliasName) return this.$message.warning(this.$t('formSetting.jsCodeBlock.aliasNoEmpty'));

        if( isRepeatName ) return this.$message.warning(this.$t('formSetting.jsCodeBlock.aliasNoRepeat'));

        if(checkJsCode(this.codeBlockConfig.codeContent)) {
          return platform.notification({
            title: i18n.t('formSetting.jsCodeBlock.testRunMsg3'),
            message: i18n.t('formSetting.jsCodeBlock.testRunMsg4'),
            type: 'warning',
          });
        }

        resolve();
      });
    },
    /** 设置完成 */
    async submit() {
      if (this.active == 2) {
        await this.checkedAliasNameIsEmptyOrRepeatAndDangerCode();
        this.update(this.codeBlockConfig);
        this.active = 0;
        this.visible = false;
        return;
      }
      if (this.active ++ >= 3) this.active = 0;
    },
    outResultAliasPath(value) {
      this.codeBlockConfig.resultAliasPath = value;
    },
    /** 编译结果值*/
    compilerResult(code, resultAliasPath = []) {
      this.analysisResults = isString(code) ? code : code.toString();
      this.codeBlockConfig.resultAliasPath = resultAliasPath;
      this.pending = !isObjectString(this.analysisResults);
    },
    /** 获取插入的表单字段 */
    getInsertFields(code = '') {
      // 插入表单字段
      let reg =/\$(.*?)\$/g;
      const matches = code.match(reg);
      const insertFields = matches ? matches.map(match => match.slice(1, -1)): [];

      return this.canInsertedFields.filter(item=> insertFields.includes(item.fieldName)) || [];
    },

    /** 代码编辑 */
    handleCodemirrorChange(code) {
      this.codeBlockConfig.codeContent = code || '';
      // 获取插入表单字段
      this.insertFields = this.getInsertFields(code);
    },
    /** 检查内容是否有修改 */
    checkModified() {
      const codeBlockConfig = this.field.setting?.codeBlockConfig || {
        automaticOperation: 0,
        codeContent:'', // js代码块
        resultAliasPath:[], // 创建别名
      };

      return JSON.stringify(this.codeBlockConfig) !== JSON.stringify(codeBlockConfig) ;
    },
    /** 关闭校验内容是否修改 */
    async onClose() {
      // 内容修改
      if(this.checkModified()) {
        const confirm = await this.$confirm(this.$t('view.designer.tip.tip4'), '', { confirmButtonText: this.$t('common.base.save'), cancelButtonText: this.$t('common.base.notSaveForNow'), type: 'warning', showClose: false, closeOnClickModal: false }).catch(() => {});
        if (!confirm){
          const codeBlockConfig = this.field.setting?.codeBlockConfig;
          let beforeValue = null;
          if(codeBlockConfig) {
            beforeValue = codeBlockConfig;
          } else {
            beforeValue = {
              automaticOperation: 0,
              codeContent:'', // js代码块
              resultAliasPath:[], // 创建别名
            };
          }
          this.codeBlockConfig = beforeValue;
          this.visible = false;
          return;
        }
        await this.checkedAliasNameIsEmptyOrRepeatAndDangerCode();

        this.update(this.codeBlockConfig);
      }
      this.visible = false;
    },
    /** 更新数据 */
    update(value) {
      const isSetting = true;
      const prop = 'codeBlockConfig';

      this.$emit('input', value, prop, isSetting);

    },
  }
};
</script>
<style lang="scss">
.compilation-test-modal {
  width:100%;
  margin: auto;
  .form-builder {
    width: 100%;
  }
  .tab-steps-body{
    padding: 10px;
    width: 760px;
    margin: auto;
    overflow: hidden;
    .tab-steps {
      width: 100%;
      margin: auto;
      padding: 20px 0px 10px 0;
    }
    .tab-step{
      height:450px;
    }
    .vue-codemirror {
      width: 100%;
      border: 1px solid #CCD4E0;
      border-radius: 4px;
      overflow: hidden;
      .CodeMirror {
        height: 360px;
        .CodeMirror-gutters {
          background: #fff;
          border-right:0px solid #ddd;
        }
        .cm-string {
          color: #10C780;
        }
      }
    }
  }
}
</style>
